(function (context) {

    var funcCache = {};
    var resultcode = [];
    var tempcode = [];
    var isvarcode = false;
    var brace = "";
    var bracecount = 0;

    var handlerPushValue = function (value) {

        if (isvarcode) {
            value = value.replace("\\\"", "\"");
        }
        tempcode.push(value);
    }

    var handlerBrace = function () {



        var remainder = bracecount % 2;
        if (remainder == 1) {
            // 左括号的 先当字符后当代码块
            // 右括号的 先当代码块再当字符串
            if (brace == '{') {
                for (var i = 0; i < parseInt(bracecount / 2); i++) {
                    handlerPushValue(brace);
                }
                handlerSwitch(brace)
            }
            else {
                handlerSwitch(brace)
                for (var i = 0; i < parseInt(bracecount / 2); i++) {
                    handlerPushValue(brace);
                }

            }
        }
        else {
            // bracecount/2 次的插入
            for (var i = 0; i < parseInt(bracecount / 2); i++) {
                handlerPushValue(brace);
            }
        }

    }


    var handlerSwitch = function (switchvalue) {
        //console.log(value);
        switch (switchvalue) {
            case "\n":

                handlerPushValue(" ");
                break;
            case "\"":
                handlerPushValue("\\\"");

                break;
            case "{":
                isvarcode = true;
                resultcode.push(" result.push(\"" + tempcode.join("") + "\") ;");
                tempcode = [];
                break;
            case "}":
                isvarcode = false;
                var varvalue = tempcode.join("");
                if (varvalue.indexOf("each") == 0) {
                    // each index,value arr  
                    var eachInfo = varvalue.split(' ');
                    if (eachInfo.length != 3) throw "each 参数无效：each index,value arr";
                    var itemInfo = eachInfo[1].split(',');
                    if (itemInfo.length != 2) throw "each 参数无效：each index,value arr";

                    resultcode.push("for (var " + itemInfo[0] + " in " + eachInfo[2] + ") {var " + itemInfo[1] + " = " + eachInfo[2] + "[" + itemInfo[0] + "];");

                }
                else if (varvalue === "/each") {
                    resultcode.push(" }");
                }
                else if (varvalue.indexOf("if") == 0) {
                    var ifInfo = varvalue.split(" ");
                    resultcode.push("if(" + ifInfo[1] + "){");
                }
                else if (varvalue.indexOf("else-if") == 0) {
                    var ifInfo = varvalue.split(" ");
                    resultcode.push(" } else if(" + ifInfo[1] + "){");
                }
                else if (varvalue.indexOf("else") == 0) {
                    var ifInfo = varvalue.split(" ");
                    resultcode.push(" } else {");
                }
                else if (varvalue.indexOf("/if") == 0) {
                    resultcode.push(" }");
                }
                else {
                    resultcode.push(" result.push(" + varvalue + ") ;");
                }
                tempcode = [];

                break;

            default:
                handlerPushValue(switchvalue);

        }
    }

    var handlerGetFuncCode = function (template) {
        resultcode = [];
        resultcode.push(" var result=[];");
        //template=template+"  ";
        for (var key in template) {
            var value = template[key];
            //if(value=='2') debugger;
            //var switchvalue = "";
            if (value == '{' || value == '}') {
                if (brace == "") {
                    brace = value;
                    bracecount = 1;
                }
                else {
                    if (brace === value) {
                        bracecount++;
                    }
                    else {

                        handlerBrace();
                        brace = value;
                        bracecount = 1;
                    }
                }
            }
            else {

                if (bracecount > 0) {
                    handlerBrace();
                    brace = "";
                    bracecount = 0;
                }
                handlerSwitch(value)
            }
        }
        if (bracecount > 0) {
            handlerBrace();
            brace = "";
            bracecount = 0;
        }
        resultcode.push(" result.push(\"" + tempcode.join("") + "\") ;");
        tempcode = [];

        resultcode.push("return result.join(\"\");")
        return resultcode.join("");
    }

    var getHashCode = function (str, caseSensitive) {
        if (!caseSensitive) {
            str = str.toLowerCase();
        }
        // 1315423911=b'1001110011001111100011010100111'
        var hash = 1315423911, i, ch;
        for (i = str.length - 1; i >= 0; i--) {
            ch = str.charCodeAt(i);
            hash ^= ((hash << 5) + ch + (hash >> 2));
        }

        return (hash & 0x7FFFFFFF);
    }
    var getFunc = function(template){
        var hascode = getHashCode(template);
        var func = funcCache[hascode];
        //console.log("funcCache[hascode]");
        //console.log(func)
        if (typeof func != "function") {
            //console.log('nothing');
            var templatecode = handlerGetFuncCode(template);
            //console.log(templatecode)
            func = new Function("data","props", templatecode);
            funcCache[hascode] = func;
        }
        return func;
    }

    var rendData = function (template, data) {
        var func = getFunc(template)
        var result = func(data);
        return result;
    }

    context.JSTemplate = {
        rendData: rendData,
        getFuncCode: handlerGetFuncCode,
        getFunc: getFunc
    }
})(window)